<?php

namespace app\common\model;

use app\common\library\task\Task;
use think\Cache;
use think\Db;
use think\Model;
use think\Queue;

/**
 * 考试成绩
 */
class ExamUserGrade extends Model
{

    protected $name = 'exam_user_grade';

    /**
     * 预载入考试成绩信息
     * @param mixed $exam_paper_id  试卷ID
     * @param mixed $user_id
     */
    public function preExamGrade($exam_paper_id, $user_id)
    {
        if (!$exam_paper_id) {
            return 0;
        }
        // 验证
        $paper = self::validExam($exam_paper_id, $user_id);
        // 检查是否已经存在
        $grade = self::where('user_id', $user_id)
            ->where('paper_id', $exam_paper_id)
            ->where('is_pre', 1) // 只查找未提交的
            ->find();
        if ($grade) {
            return ['exam_grade_id' => $grade['id'], 'grade_time' => $grade['grade_time']]; //返回已存在的ID
        }
        // 创建考场考试记录
        $grade = self::create([
            'user_id'     => $user_id,
            'mode'        => $paper['mode'],
            'paper_id'    => $exam_paper_id,
            'exam_cate_id' => $paper['exam_cate_id'],
            // 'teacher_id'    => $exam['teacher_id'],
            'score'       => 0,
            'is_pass'     => 0,
            'total_score' => $paper['total_score'],
            'total_count' => $paper['quantity'],
            'right_count' => 0,
            'error_count' => $paper['quantity'],
            'limit_time'  => $paper['limit_time'],
            'rank'        => 0, //排名
            'is_pre'      => 1, // 标记为预载入，提交成绩时须改为0
            'grade_time'  => 0  // 考试使用时间，单位秒
        ]);
        return ['exam_grade_id' => $grade['id'], 'grade_time' => $grade['grade_time']];
    }



    /**
     * 验证码考试信息和试卷信息
     * @param mixed $user_id
     * @param mixed $exam_id
     */
    public static function validExam($exam_paper_id, $user_id = 0)
    {
        # 查询当前用户是否报名通过
        $signup_status = Db::name('exam_user_signup')->where('user_id', $user_id)->value('status');
        if ($signup_status != 1) {
            fail('请先报名');
        }
        # 验证考试信息
        $paper  = (new Exampaper())->where('id', $exam_paper_id)->find();
        # 验证试卷信息
        switch (true) {
            case !$paper:
                fail('试卷信息不存在');
            case $paper->status != "NORMAL":
                fail('试卷未开启');
            case $paper->mode == "RANDOM" && !$paper->configs:
                fail('试卷未配置');
            case $paper->start_time != 0 && (time() < $paper->start_time || time() > $paper->end_time):
                fail('考场时间未开始或已结束');
            case $paper->end_time != 0 && $paper->end_time > 0 && $paper->end_time < time():
                fail('该试卷已失效，不能参与考试了');
        }
        if ($user_id) {
            # 查询用户是否结束考试
            $is_pre = self::where(['paper_id' => $exam_paper_id, 'user_id' => $user_id])->value('is_pre', 1);
            if ($is_pre == 0) {
                fail('该用户已结束考试');
            }
        }
        return $paper;
    }


    /**
     * 考试结果
     */
    public function getExamGradeInfo($paper_id, $user_id)
    {
        $info = self::where([
            'user_id' => $user_id,
            'paper_id' => $paper_id
        ])->field('id as exam_grade_id,user_id,read,paper_id,user_answers,mode,score,system_score,manual_score,total_score,total_count,right_count,error_count,grade_time')->find();
        if (empty($info)) {
            return [];
        }
        # 查询用户答案
        $user_answers = json_decode($info->user_answers, true);
        // 计算 is_right = -1 的个数，未答数量
        $not_answered = count(array_filter($user_answers, function ($item) {
            return isset($item['is_right']) && $item['is_right'] == -1;
        }));
        $info->error_count  = $info->error_count - $not_answered;  # 答错误题数量
        $info->not_answere_count  =  $not_answered; # 未答题数量
        $info->user_answers = $user_answers;
        # 查询试卷 结束时间 判断是否可以查询排行
        $end_time = (new Exampaper())->where('id', $paper_id)->value('end_time');
        $info->paper_can_rank = $end_time > time() ? 1 : 0;
        $info->paper_end_time = $end_time;
        return $info;
    }


    /**
     * 查询考试解析
     */
    public function  getExamGradeQuestion($exam_grade_id)
    {
        $info = self::where('id', $exam_grade_id)->field('mode, user_answers,question_ids')->find();
        if (empty($info)) {
            return [];
        }
        # 固定选题
        $questions = (new Question())->getUserAnalysisQuestions($info->question_ids);
        // 将题目数组按 question_id 重新索引，方便匹配
        $questions_by_id = [];
        foreach ($questions as $question) {
            $questions_by_id[$question['question_id']] = $question;
        }
        $user_answers = json_decode($info->user_answers, true);
        foreach ($user_answers as $key => $value) {
            $question_id = $value['question_id'];
            // 根据 question_id 匹配对应的题目信息
            $user_answers[$key]['question'] = isset($questions_by_id[$question_id]) ? $questions_by_id[$question_id] : null;
        }
        return $user_answers;
    }

    /**
     * 考试排行
     */
    public function getRankList($paper_id, $user_id) {
        $order = ["eg.score" => "desc", "eg.grade_time" => "asc"];  # 根据分数和时间排序
        $list = self::alias('eg')
            ->join('user u', 'eg.user_id = u.id', 'left')
            ->where([
                'eg.paper_id' => $paper_id,
                'eg.is_pre' => "0"  # 只查询已提交考试的用户
            ])->field('eg.id,eg.user_id,eg.score,eg.grade_time,u.nickname,u.avatar')->order($order)->select();
        $list = collection((array)$list)->toArray();
        # 更新用户排行
        Queue::push(Task::class, ['type' => 'rank', 'data' => $list]);
        $result = [
            'list' => $list,
            'user_rank' => null
        ];
        # 查询用户自己排名
        if ($user_id > 0) {
            // 查询用户在全国的排行
            $user_rank_in_total = 0;
            $user_info = null;
            foreach ($list as $index => $item) {
                if ($item['user_id'] == $user_id) {
                    $user_rank_in_total = $index + 1;
                    $user_info = $item;
                    break;
                }
            }
            $result['user_rank'] = [
                'rank' => $user_rank_in_total,
                'nickname' => $user_info ? $user_info['nickname'] : '',
                'avatar' => $user_info ? $user_info['avatar'] : '',
                'score' => $user_info ? $user_info['score'] : 0
            ];
        }
        return $result;
    }
}
